/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2013-2014 sagyf Yang. The Four Group.
 */

package app;

import app.models.sys.AuthResources;
import app.models.sys.AuthUsers;
import com.github.sog.controller.security.AppUser;
import com.github.sog.kit.encry.EncodeKit;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;

/**
 * <p>
 * 处理用户登录.
 * </p>
 *
 * @author sagyf yang
 * @version 1.0 2014-04-09 21:17
 * @since JDK 1.6
 */
public class AppDbRealm extends AuthorizingRealm {

    public AppDbRealm() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(EncodeKit.HASH_ALGORITHM);
        matcher.setHashIterations(EncodeKit.HASH_INTERATIONS);

        setCredentialsMatcher(matcher);
    }

    //授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
    //如果他的角色是admin，info会得到所有权限+角色字段，如果不是，info里面只有角色字段
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        final AppUser user = (AppUser) principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        AuthUsers db_user = AuthUsers.dao.findById(user.getId());
        if (StringUtils.equals(db_user.getStr("role"), "admin")) {
            info.addRole("admin");
            List<AuthResources> resourceses = AuthResources.dao.list();
            for (AuthResources resourcese : resourceses) {
                info.addStringPermission(resourcese.getStr("action"));
            }
        } else {
            info.addRole(db_user.getStr("role"));
        }

        return info;
    }


    /*认证回调函数, 登录时调用.*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        // 调用操作数据库的方法查询user信息
        AuthUsers user = AuthUsers.dao.findByName(token.getUsername());
        if (user != null) {
            byte[] salt = EncodeKit.decodeHex(user.getStr("salt"));
            AppUser shiroEmployee = new AppUser(
                    user.getInt("id"),
                    user.getStr("name"), null,
                    user.getStr("real_name"), null,
                    user.getBoolean("super_admin"));
            return new SimpleAuthenticationInfo(shiroEmployee, user.getStr("password"), ByteSource.Util.bytes(salt), getName());
        } else {
            return null;
        }
    }
}
